package io.adrainty.bolee.trade.feign.impl;

import io.adrainty.bolee.framework.commons.basic.ResponseCode;
import io.adrainty.bolee.framework.commons.basic.ResultDTO;
import io.adrainty.bolee.framework.commons.exception.AppException;
import io.adrainty.bolee.framework.commons.utils.ResultDTOUtil;
import io.adrainty.bolee.trade.feign.IWapPayFeign;
import io.adrainty.bolee.trade.handler.IPayHandler;
import io.adrainty.bolee.trade.handler.PayHandlerRegistry;
import io.adrainty.bolee.trade.models.constants.TradeCacheConstants;
import io.adrainty.bolee.trade.models.entity.TradeEntity;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

/**
 * <p>WapPayFeignImpl</p>
 *
 * @author AdRainty
 * @version V1.0.0
 * @description 手机网页支付feign接口
 * @since 2025/8/28 13:54:20
 */

@Slf4j
@RestController
@Tag(name = "手机网页支付feign接口")
@RequestMapping("/trade-wap-feign")
public class WapPayFeignImpl implements IWapPayFeign {

    @Resource
    private PayHandlerRegistry handlerRegistry;

    @Resource
    private RedissonClient redissonClient;

    @Override
    @PostMapping("/wap-trade")
    @Operation(summary = "手机网页支付")
    public ResultDTO<TradeEntity> wapTrade(@RequestBody TradeEntity tradeVO) {
        // 对交易订单加锁
        Long productOrderNo = tradeVO.getProductOrderNo();
        String key = TradeCacheConstants.CREATE_PAY + productOrderNo;
        RLock lock = redissonClient.getLock(key);
        try {
            if (lock.tryLock(TradeCacheConstants.REDIS_WAIT_TIME, TimeUnit.SECONDS)) {
                IPayHandler payHandler = handlerRegistry.strictGetPayChannel(tradeVO.getTradeChannel());
                TradeEntity result = payHandler.wapTrade(tradeVO);
                return ResultDTOUtil.success(result);
            } else {
                throw new AppException(ResponseCode.LOCK_ERROR);
            }
        } catch (Exception e) {
            log.error("wapTrade error: ", e);
            if (e instanceof AppException ae) {
                throw ae;
            } else {
                throw new AppException(ResponseCode.TRADE_ERROR);
            }
        }
    }

}
